#include "GrayValueMeasurementAlgorithm.h"
#include "GrayValueMeasurementResultWidget.h"
#include <QDebug>
#include <QImage>
#include <QPoint>

GrayValueMeasurementAlgorithm::GrayValueMeasurementAlgorithm(QObject *parent)
    : MeasurementAlgorithmBase(parent),
      m_resultWidget(nullptr),
      m_drawerFactory(std::make_unique<GrayValueMeasurementDrawerFactory>(this)) {
    // 连接绘制器工厂的信号
    connect(m_drawerFactory.get(), &GrayValueMeasurementDrawerFactory::rectangleChanged, 
            this, &GrayValueMeasurementAlgorithm::onRectangleChanged);
    connect(m_drawerFactory.get(), &GrayValueMeasurementDrawerFactory::horizontalLineChanged, 
            this, [this](const QLineF &line) {
                onLineChanged(line);
            });
    connect(m_drawerFactory.get(), &GrayValueMeasurementDrawerFactory::verticalLineChanged, 
            this, [this](const QLineF &line) {
                onLineChanged(line);
            });
}

GrayValueMeasurementAlgorithm::~GrayValueMeasurementAlgorithm()
{
    // 清理资源
    if (m_resultWidget) {
        delete m_resultWidget;
        m_resultWidget = nullptr;
    }
}

QString GrayValueMeasurementAlgorithm::algorithmName() const
{
    return tr("灰度值测量");
}

void GrayValueMeasurementAlgorithm::initialize() {
    // 创建结果显示窗口
    m_resultWidget = new GrayValueMeasurementResultWidget();

    // 连接信号和槽，使用lambda函数处理参数不匹配问题
    connect(this, &GrayValueMeasurementAlgorithm::measurementProcessed,
            m_resultWidget, [this](const QString &, const QVariantMap &result) {
                m_resultWidget->updateGrayValueResult(result);
            });

    // 注册算法名称和图标，用于显示按钮
    emit registerMeasurementAlgorithm(algorithmName(), ":/images/images/15.png");
}

MeasurementModes GrayValueMeasurementAlgorithm::getSupportedModes() const
{
    MeasurementModes modes;
    modes.setFlag(MeasurementMode::HorizontalSingleLine);
    modes.setFlag(MeasurementMode::VerticalSingleLine);
    modes.setFlag(MeasurementMode::RectangleRegion);
    return modes;
}

void GrayValueMeasurementAlgorithm::startMeasurement(const QString &imageId)
{
    m_imageId = imageId;
    m_processed = true;
    if (m_resultWidget)
    {
        emit registerMeasurementResultWidget(algorithmName(), m_resultWidget);
    }
}

void GrayValueMeasurementAlgorithm::endMeasurement()
{
    m_imageId.clear();
    m_drawerFactory->clearAll();
    m_processed = false;
}

QString GrayValueMeasurementAlgorithm::currentImageId() const
{
    return m_imageId;
}

QVariantMap GrayValueMeasurementAlgorithm::getMeasurementParameters() const
{
    return m_params;
}

void GrayValueMeasurementAlgorithm::setMeasurementParameters(const QVariantMap &params)
{
    m_params = params;
    // 从参数中提取并绘制测量图形
    drawMeasurementGraphics(params);
}

void GrayValueMeasurementAlgorithm::drawMeasurementGraphics(const QVariantMap &params)
{
    // 从参数中提取测量类型
    if (!params.contains("MeasurementType")) {
        qWarning() << "MeasurementType is no find";
        return;
    }
    
    // 从参数中获取图形场景
    if (params.contains("Canvas")) {
        QGraphicsScene *scene = params.value("Canvas").value<QGraphicsScene*>();
        if (scene) {
            // 设置场景给绘制器工厂
            if (m_drawerFactory) {
                m_drawerFactory->setScene(scene);
            }
        }
    }
    
    // 获取测量类型并转换为MeasurementMode枚举
    QString measurementType = params.value("MeasurementType").toString();
    MeasurementMode mode = MeasurementMode::HorizontalSingleLine; // 默认模式
    
    // 根据字符串测量类型转换为枚举值
    if (measurementType == "HorizontalSingleLine") {
        mode = MeasurementMode::HorizontalSingleLine;
    } else if (measurementType == "VerticalSingleLine") {
        mode = MeasurementMode::VerticalSingleLine;
    } else if (measurementType == "RectangleRegion") {
        mode = MeasurementMode::RectangleRegion;
    } else {
        qWarning() << "MeasurementMode error:" << measurementType;
        return;
    }
    
    // 获取显示图像并从中提取图像尺寸
    int imageWidth = 0;
    int imageHeight = 0;
    
    if (params.contains("DisplayImage")) {
        QImage image = params.value("DisplayImage").value<QImage>();
        if (!image.isNull()) {
            imageWidth = image.width();
            imageHeight = image.height();
        }
    }
    
    if (imageWidth <= 0 || imageHeight <= 0) {
        qWarning() << "image size error";
        return;
    }
    
    // 获取缩放比例（默认为1.0）
    double scale = 1.0;
    if (params.contains("ImageScale")) {
        scale = params.value("ImageScale").toDouble();
    }
    
    // 获取图像偏移信息
    QPointF offset(0.0, 0.0);
    if (params.contains("ImageOffset")) {
        QSize offsetSize = params.value("ImageOffset").value<QSize>();
        offset.setX(offsetSize.width());
        offset.setY(offsetSize.height());
    }
    
    // 初始化测量工具并绘制图形
    if (m_drawerFactory) {
        m_drawerFactory->initializeMeasurementTool(mode, imageWidth, imageHeight, scale, offset);
    }
}

/**
 * @brief 设置测量结果（用于撤销/重做操作）
 * @param imageId 图像唯一标识符
 * @param measurementResult 测量结果，包含灰度值数据
 *
 * 该方法直接设置测量结果而不重新计算，用于撤销/重做操作时恢复之前的测量状态。
 * 它会更新内部状态、注册结果显示界面并发送测量结果信号。
 */
void GrayValueMeasurementAlgorithm::setMeasurementResult(const QVariantMap &measurementResult)
{
    // 设置图像ID和测量结果
    m_processed = true;

    // 注册结果显示界面
    if (m_resultWidget) {
        emit registerMeasurementResultWidget(algorithmName(), m_resultWidget);
        // 更新结果显示窗口
        m_resultWidget->updateGrayValueResult(measurementResult);
    }
}

void GrayValueMeasurementAlgorithm::onRectangleChanged(const QRectF &rect)
{
    // 获取当前图像
    QImage image = m_params.value("DisplayImage").value<QImage>();
    if (image.isNull()) {
        qWarning() << "DisplayImage Error";
        return;
    }

    QVariantMap result;

    // 确保矩形坐标在有效范围内
    int startX = qMax(0, static_cast<int>(rect.left()));
    int startY = qMax(0, static_cast<int>(rect.top()));
    int endX = qMin(image.width() - 1, static_cast<int>(rect.right()));
    int endY = qMin(image.height() - 1, static_cast<int>(rect.bottom()));

    if (startX > endX || startY > endY) {
        qWarning() << "矩形区域超出图像范围";
        return;
    }

    // 计算矩形内所有像素的灰度值
    QList<int> grayValues;
    for (int y = startY; y <= endY; ++y) {
        for (int x = startX; x <= endX; ++x) {
            grayValues.append(qGray(image.pixel(x, y)));
        }
    }

    // 计算统计信息
    if (!grayValues.isEmpty()) {
        int sum = 0;
        int minValue = 255;
        int maxValue = 0;

        foreach (int value, grayValues) {
            sum += value;
            minValue = qMin(minValue, value);
            maxValue = qMax(maxValue, value);
        }

        double average = static_cast<double>(sum) / grayValues.size();

        // 保存测量结果
        result["gray_values"] = QVariant::fromValue(grayValues);
        result["average_gray"] = average;
        result["min_gray"] = minValue;
        result["max_gray"] = maxValue;
        result["pixel_count"] = grayValues.size();
        result["measurement_type"] = "RectangleRegion";

        // 保存矩形参数
        result["x"] = startX;
        result["y"] = startY;
        result["width"] = endX - startX + 1;
        result["height"] = endY - startY + 1;
    }

    // 发送测量结果
    emit measurementProcessed(m_imageId, result);
}

void GrayValueMeasurementAlgorithm::setScale(double scale)
{
    // 实现缩放比例设置
    qDebug() << "Setting scale for GrayValueMeasurementAlgorithm:" << scale;
    // 保存缩放比例到参数中
    m_params["ImageScale"] = scale;
    
    // 更新绘制器的缩放比例
    if (m_drawerFactory) {
        m_drawerFactory->updateScale(scale);
    }
}

void GrayValueMeasurementAlgorithm::setUnitConversionInfo(int xUnit, int yUnit, double lengthRatio,
                                                       double timeRatio, double wavelengthRatio, 
                                                       const QString &lengthUnit, const QString &timeUnit, 
                                                       const QString &wavelengthUnit)
{
    // 构建单位转换映射，用于测量计算
    QVariantMap unitConversionMap;
    unitConversionMap["xAxisUnit"] = xUnit;
    unitConversionMap["yAxisUnit"] = yUnit;
    unitConversionMap["lengthRatio"] = lengthRatio;
    unitConversionMap["timeRatio"] = timeRatio;
    unitConversionMap["wavelengthRatio"] = wavelengthRatio;
    unitConversionMap["lengthUnit"] = lengthUnit;
    unitConversionMap["timeUnit"] = timeUnit;
    unitConversionMap["wavelengthUnit"] = wavelengthUnit;

    m_params["UnitConversion"] = unitConversionMap;
}

void GrayValueMeasurementAlgorithm::onLineChanged(const QLineF &lineImage)
{
    // 获取当前图像
    QImage image = m_params.value("DisplayImage").value<QImage>();
    if (image.isNull()) {
        qWarning() << "DisplayImage Error";
        return;
    }

    QVariantMap result;

    // 确保坐标在有效范围内
    QPoint start(static_cast<int>(lineImage.p1().x()), static_cast<int>(lineImage.p1().y()));
    QPoint end(static_cast<int>(lineImage.p2().x()), static_cast<int>(lineImage.p2().y()));

    start.setX(qMax(0, qMin(image.width() - 1, start.x())));
    start.setY(qMax(0, qMin(image.height() - 1, start.y())));
    end.setX(qMax(0, qMin(image.width() - 1, end.x())));
    end.setY(qMax(0, qMin(image.height() - 1, end.y())));

    // 使用Bresenham算法绘制线段并获取像素点
    QList<QPoint> points;
    int x0 = start.x(), y0 = start.y();
    int x1 = end.x(), y1 = end.y();

    bool steep = qAbs(y1 - y0) > qAbs(x1 - x0);
    if (steep) {
        qSwap(x0, y0);
        qSwap(x1, y1);
    }

    if (x0 > x1) {
        qSwap(x0, x1);
        qSwap(y0, y1);
    }

    int dx = x1 - x0;
    int dy = qAbs(y1 - y0);
    int error = dx / 2;
    int ystep = (y0 < y1) ? 1 : -1;
    int y = y0;

    for (int x = x0; x <= x1; ++x) {
        if (steep) {
            points.append(QPoint(y, x));
        } else {
            points.append(QPoint(x, y));
        }

        error -= dy;
        if (error < 0) {
            y += ystep;
            error += dx;
        }
    }

    // 获取线段上的灰度值
    QList<int> grayValues;
    foreach (const QPoint &pt, points) {
        if (pt.x() >= 0 && pt.x() < image.width() && pt.y() >= 0 && pt.y() < image.height()) {
            grayValues.append(qGray(image.pixel(pt)));
        }
    }

    // 计算统计信息
    if (!grayValues.isEmpty()) {
        int sum = 0;
        int minValue = 255;
        int maxValue = 0;

        foreach (int value, grayValues) {
            sum += value;
            minValue = qMin(minValue, value);
            maxValue = qMax(maxValue, value);
        }

        double average = static_cast<double>(sum) / grayValues.size();

        // 保存测量结果
        result["gray_values"] = QVariant::fromValue(grayValues);
        result["average_gray"] = average;
        result["min_gray"] = minValue;
        result["max_gray"] = maxValue;
        result["pixel_count"] = grayValues.size();

        // 保存线段参数
        result["start_x"] = start.x();
        result["start_y"] = start.y();
        result["end_x"] = end.x();
        result["end_y"] = end.y();

        // 确定测量类型（水平或垂直）
        if (qAbs(start.y() - end.y()) < qAbs(start.x() - end.x())) {
            result["measurement_type"] = "HorizontalSingleLine";
        } else {
            result["measurement_type"] = "VerticalSingleLine";
        }
    }

    // 发送测量结果
    emit measurementProcessed(m_imageId, result);
}

